#include "threadPool.h"


int generate_salt(char *salt) {
    //定义字符集（包含大小写字母、数字及特殊字符）
    const char charset[] = "abcdefghijklmnopqrstuvwxyz"
                          "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                          "0123456789!@#$%^&*()_+-=[]{}|;:,.<>?";
    //分配内存（包含结束符'\0'）
    char *psalt = (char*)malloc(21 * sizeof(char));
    if (!psalt) 
        return -1;
    srand(time(NULL) ^ (getpid() << 16)); // 混合时间和进程ID增强随机性
    psalt[0] = '$';
    //生成中间18个随机字符
    const size_t charset_size = strlen(charset);
    for (int i = 1; i < 19; ++i) {
        psalt[i] = charset[rand() % charset_size]; // 从字符集随机选取
    }
    psalt[19] = '$';
    psalt[20] = '\0';
    strncpy(salt, psalt, 21);
    return 0;
}

// 用户名，盐值插入(会在调用生成盐值后执行该操作)
int user_insert(const char *usrName, const char *salt, MYSQL *conn){
    char sql[256]={0};
    snprintf(sql, sizeof(sql),"INSERT INTO userSystem (username, salt) VALUES ('%s', '%s')",usrName, salt);
    int qret = mysql_query(conn, sql);
    if (qret != 0) {
        printf("ERROR: %s\n", mysql_error(conn));
        return -1;
    }
    return 0;
}


// 新用户的文件表插入表（即第一行插入）,在注册操作完成之后立即调用
int user_file_insert(const char *usrName,MYSQL *conn){
    char sql[256]={0};
    snprintf(sql,sizeof(sql),"INSERT INTO fileSystem(filename,username,parent_id,fileComment,type,path) VALUES('/','%s','NULL','NULL','d','/')",usrName);
    int qret = mysql_query(conn,sql);
    if(qret!=0){
        printf("ERROR:%s\n",mysql_error(conn));
        return -1;
    }
    return 0;
}

int user_exist(const char* usrName, MYSQL *conn){
    char sql[256]={0};
    snprintf(sql, sizeof(sql), "SELECT 1 FROM userSystem WHERE username='%s' LIMIT 1", usrName);

    int qret = mysql_query(conn, sql);
    if (qret != 0) {
        printf("ERROR: %s\n", mysql_error(conn));
        return -1;
    }

    MYSQL_RES *res = mysql_store_result(conn);
    if (res == NULL) {
        printf("No result returned\n");
        return -1;
    }
    long row_count = mysql_num_rows(res);
    mysql_free_result(res);

    if (row_count > 0) {
        return 0; // 用户存在
    } else {
        return -1; // 用户不存在
    }
}


int getsalt(const char *usrName,char *salt,MYSQL *conn){
    char sql[256]={0};
    snprintf(sql,sizeof(sql),"SELECT salt FROM userSystem WHERE username = '%s'",usrName);
    int qret = mysql_query(conn,sql);
    if(qret!=0){
        printf("ERROR :%s\n",mysql_error(conn));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(conn);
    if(res == NULL){
        printf("No result returned\n");
        return -1;
    }
    MYSQL_ROW row = mysql_fetch_row(res);
    if(row && row[0]){  // 找到对应盐值
        strcpy(salt,row[0]);
        mysql_free_result(res);
        return 0;
    }else{ // 查找盐值失败
        mysql_free_result(res);
        return -1;
    }
}

int make_salt(const char *usrName,char *salt,MYSQL *conn){
    char new_salt[20]={0};
    int ret = generate_salt(new_salt);
    if(ret!=0){
        return -1;
    }
    strcpy(salt,new_salt);
    return 0;
}

// 服务端处理用户登录接口函数
int user_login(const char *usrName,char *ciphertxt,MYSQL *conn){

    char sql[256]={0};
    // V1.0
    // 风险:因为直接用的字符串拼接，那么就会面临sql注入的风险问题，后续V 2.0 会引入prepare statement 来防止sql注入
    snprintf(sql,sizeof(sql),"SELECT 1 FROM userSystem WHERE username='%s' AND password_hash='%s' LIMIT 1",usrName,ciphertxt);
    int qret = mysql_query(conn,sql);
    if(qret!=0){
        printf("ERROR: %s\n", mysql_error(conn));
        return -1;
    }

    MYSQL_RES *res = mysql_store_result(conn);
    if (res == NULL) {
        printf("No result returned\n");
        return -1;
    }
    long row_count = mysql_num_rows(res);
    mysql_free_result(res);

    if (row_count > 0) {
        return 0; // 密码校验成功
    } else {
        return -1; // 密码校验失败
    }
}

// 服务端处理用户注册接口函数
int user_regist(const char *usrName,const char *ciphertxt,MYSQL *conn){
    char sql[256]={0};
    snprintf(sql, sizeof(sql),"UPDATE userSystem SET password_hash='%s' WHERE username='%s'", ciphertxt, usrName);

    int qret = mysql_query(conn, sql);
    if (qret != 0) {
        printf("ERROR: %s\n", mysql_error(conn));
        return -1;
    }

    // 可以根据mysql_affected_rows(conn)判断是否真的有更新成功
    if (mysql_affected_rows(conn) == 1) {
        return 0; // 更新成功
    } else {
        return 1; // 没有此用户名或未成功更新
    }
}

// 查找文件表中用户名对应的id
int get_uid_fileSystem(const char *usrName,MYSQL *conn){
    char sql[256]={0};
    snprintf(sql,sizeof(sql),"SELECT 1 FROM fileSystem WHERE username ='%s'",usrName);
    int qret = mysql_query(conn,sql);
    if(qret){
        printf("ERROR: %s\n", mysql_error(conn));
        return -1;
    }

    MYSQL_RES *res = mysql_store_result(conn);
    if (res == NULL) {
        printf("No result returned\n");
        return -1;
    }
    MYSQL_ROW row = mysql_fetch_row(res);
    int id = -1;
    if (row) {
        // row[0] 就是 id 字段
        id = atoi(row[0]);
    }
    mysql_free_result(res);

    return id; // 如果没查到，id=-1。查到就返回真实id    
}
